<?php
/**
 * Created by PhpStorm.
 * User: shaowei
 * Date: 2019/5/11
 * Time: 下午3:25
 */

namespace App\Lib;

use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;


class xdpay
{
    /**
     * md5加密
     * @param $arrData
     * @param $strKey
     * @return array
     */
    public function md5Sign($arrData,$strKey){
        $arrRes = array();
        if(!$strKey){
            return $arrRes;
        }
        //对待签名参数数组排序
        $arrData = $this->argSort($arrData);
        //
        $arrData['key']= $strKey;
        $strData = http_build_query($arrData);
        $strData = urldecode($strData);
        $arrRes['params'] = $strData;
        $arrRes['sign']   = md5($strData);
        return $arrRes;
    }

    /**
     * 对数组排序
     * @param $arrParam
     * @return mixed
     */
    public function argSort($arrParam){
        ksort($arrParam);
        reset($arrParam);
        return $arrParam;
    }

    /**
     * md5签名校验
     * @param $arrData 待签名数据
     * @param $strKey 商户合作密钥
     * @return bool 是否通过 bool值
     */
    public function md5Verify($arrData,$strKey){
        if(!isset($arrData['sign'])){
            return false;
        }
        $strInputSign = $arrData['sign'];
        unset($arrData['sign']);

        $arrSign = $this->md5Sign($arrData,$strKey);
        if(empty($arrSign)){
            return false;
        }
        return ($strInputSign==$arrSign['sign']) ? true : false;
    }

    /**
     * RSA签名
     * @param $arrData
     * @param $strPrivateKeyFile
     * @return string
     */
    public function rsaSign($arrData,$strPrivateKeyFile){
        $strSign = '';
        if(empty($strPrivateKeyFile)){
            return $strSign;
        }
        $arrData = $this->argSort($arrData);
        $strData = http_build_query($arrData);
        $strData = urldecode($strData);
        $strPrivateKey = $strPrivateKeyFile;
        // 转换为openssl密钥，必须是没有经过pkcs8转换的私钥
        $getRes = openssl_get_privatekey($strPrivateKey);
        ($getRes) or die('您使用的私钥格式错误，请检查RSA私钥配置');
        // 调用openssl内置签名方法，生成签名$sign
        openssl_sign($strData, $strSign, $getRes);
        // 释放资源
        openssl_free_key($getRes);
        // base64编码
        $strSign = base64_encode($strSign);
        return $strSign;
    }

    /**
     * RSA验签
     * @param $arrData
     * @param $strSign
     * @param $strPublicKeyFile 公钥
     * @return bool
     */
    public function rsaVerify($arrData,$strPublicKey){
        if(empty($strPublicKey)){
            return false;
        }
        $strSign = $arrData['sign'];
        unset( $arrData['sign']);
        unset($arrData['nsukey']);
        $arrSortData = $this->argSort($arrData);
        $strData = http_build_query($arrSortData);
        $strData = urldecode($strData);
        $publicKey = "-----BEGIN PUBLIC KEY-----\n$strPublicKey\n-----END PUBLIC KEY-----";
        // 转换为openssl格式密钥
        $objRes = openssl_get_publickey($publicKey);
        ($objRes) or die('小度支付RSA公钥错误。请检查公钥文件格式是否正确');
        // 调用openssl内置方法验签，返回bool值
        $result = (bool) openssl_verify($strData, base64_decode($strSign), $objRes);
        // 释放资源
        openssl_free_key($objRes);
        return $result;
    }
}